package gggameserver.games.stopgate;

import gggameserver.games.Board;
import gggameserver.games.Move;

import java.util.StringTokenizer;

public class StopGateBoard extends Board {

	public static final int EMPTY = 0;
	public static final int TOP = 1;
	public static final int DOWN = 2;
	public static final int LEFT = 3;
	public static final int RIGHT = 4;

	private int width;
	private int height;
	private int[][] board;

	public StopGateBoard(int width, int height) {
		super(2);
		this.width = width;
		this.height = height;

		this.addPlayer(new StopGatePlayer(this));
		this.addPlayer(new StopGatePlayer(this));

		this.board = new int[this.width][this.height];
		for (int i = 0; i < this.width; i++)
			for (int j = 0; j < this.height; j++)
				board[i][j] = EMPTY;
	}

	@Override
	public boolean isLeagal(Move move) {
		return makeMove(move, false);
	}

	@Override
	public void makeMove(Move move) {
		makeMove(move, true);
		checkGameOver();
	}

	/**
	 * @param move
	 * @param make_move
	 *            true - real move, false - just check, if it's leagal move
	 * @return
	 */
	private boolean makeMove(Move move, boolean make_move) {
		StopGateMove sg_move = (StopGateMove) move;

		boolean first_player = 1 == sg_move.getPlayerNumber();

		int x1 = sg_move.getX();
		int y1 = sg_move.getY();
		int x2 = x1 + (first_player ? 0 : 1);
		int y2 = y1 + (first_player ? 1 : 0);

		if (!isFree(x1, y1))
			return false;
		if (!isFree(x2, y2))
			return false;

		if (make_move) {
			// real move not a check
			if (first_player) {
				this.board[x1][y1] = DOWN;
				this.board[x2][y2] = TOP;
			} else {
				this.board[x1][y1] = LEFT;
				this.board[x2][y2] = RIGHT;
			}

			// switch player
			moveToNextPlayer();
			// check if game is over
			checkGameOver();
		}

		// printBoard();
		return true;
	}

	public void printBoard() {
		// TODO
		for (int j = this.height - 1; j >= 0; j--) {
			for (int i = 0; i < this.width; i++)
				switch (this.board[i][j]) {
				case EMPTY:
					System.out.print('.');
					break;
				case TOP:
					System.out.print('A');
					break;
				case DOWN:
					System.out.print('V');
					break;
				case LEFT:
					System.out.print('<');
					break;
				case RIGHT:
					System.out.print('>');
					break;
				default:
					System.out.print('?');
				}
			System.out.println();
		}
		System.out.println();
		// TODO
	}

	private void checkGameOver() {
		if (!activePlayerHasMove()) {
			setLoser(getActivePlayer());
		}
	}

	private boolean activePlayerHasMove() {
		boolean first_player = 1 == getActivePlayer().getPlayerNumber();

		for (int x1 = 0; x1 < this.width; x1++)
			for (int y1 = 0; y1 < this.height; y1++) {
				int x2 = x1 + (first_player ? 0 : 1);
				int y2 = y1 + (first_player ? 1 : 0);

				if (isFree(x1, y1) && isFree(x2, y2))
					return true;
			}

		return false;
	}

	private boolean isFree(int x, int y) {
		if (x < 0 || this.width <= x || y < 0 || this.height <= y)
			return false;
		return this.board[x][y] == EMPTY;
	}

	public int getCell(int x, int y) {
		return this.board[x][y];
	}

	@Override
	public Move commandToMoveSimple(String command) throws Exception {
		// TODO
		StringTokenizer st = new StringTokenizer(command);
		return new StopGateMove(getActivePlayer().getPlayerNumber(),
				Integer.parseInt(st.nextToken()), Integer.parseInt(st
						.nextToken()));
	}

	@Override
	public String moveToCommand(Move move) {
		StopGateMove sg_move = (StopGateMove) move;
		return sg_move.getX() + " " + sg_move.getY();
	}

}
